use chrono::Local;
use sqlite_wasm_rs::sqlite3_stmt;
use crate::db::db::{Db, DbParamType};
use crate::db::pojo::pojo::{ImConfig};
use crate::db::util::{db_get_int, db_get_int64, db_get_string};
use crate::util::time::parse_to_time;

pub fn config_inserts(db: Db, configs: Vec<&mut ImConfig>) {
    if configs.is_empty() {
        return;
    }

    let sql = c"insert into im_config(currentUserId, name, content, status, createTime, updateTime) values(?, ?, ?, ?, ?, ?)";

    let mut params = vec![];
    for config in configs.iter() {
        let mut param = vec![];
        param.push(DbParamType::Str(&*config.current_user_id));
        param.push(DbParamType::Str(&*config.name));
        param.push(DbParamType::Str(&*config.content));
        param.push(DbParamType::Byte(config.status.clone() as i8));
        param.push(DbParamType::DateTime2(&config.create_time));
        param.push(DbParamType::DateTime2(&config.update_time));
        params.push(param);
    }

    db.inserts("config insert", sql, params);
}

pub fn config_updates(db: Db, configs: Vec<&mut ImConfig>) {
    if configs.is_empty() {
        return;
    }
    let sql = "update im_config set content = ?, updateTime = ? where currentUserId = ? and name = ?";
    let mut params = vec![];
    for config in configs.iter() {
        let mut param = vec![];
        param.push(DbParamType::Str(&*config.content));
        param.push(DbParamType::DateTime(Local::now()));
        param.push(DbParamType::Str(&*config.current_user_id));
        param.push(DbParamType::Str(&*config.name));
        params.push(param);
    }
    log::info!("db config update params: {:?}", params);
    db.batch_exec("config update", sql.to_string(), params);
}

pub fn config_query_by_names(db: Db, current_user_id: &String, names: Vec<&String>) -> Vec<ImConfig> {
    if names.is_empty() { return Vec::new(); }
    let sql_where = names.iter().map(|_code| "?").collect::<Vec<&str>>().join(",");
    let sql = format!("SELECT id, currentUserId, name, content, status, createTime, updateTime FROM im_config where currentUserId = ? and name in ({})", sql_where);
    let mut params = vec![];

    params.push(DbParamType::Str(current_user_id));
    names.into_iter().for_each(|name| {
        params.push(DbParamType::Str(name));
    });
    db.query2("config query", sql.as_str(), params, Box::new(config_wrap))
}

fn config_wrap(stmt: *mut sqlite3_stmt)-> ImConfig {
    unsafe {
        let id = db_get_int64(stmt, 0);
        let current_user_id = db_get_string(stmt, 1).unwrap();
        let name = db_get_string(stmt, 2).unwrap();
        let content = db_get_string(stmt, 3).unwrap();
        let status = db_get_int(stmt, 4);
        let create_time_str = db_get_string(stmt, 5).unwrap();
        let update_time_str = db_get_string(stmt, 6).unwrap();

        let status2 = serde_json::from_str(status.to_string().as_str()).unwrap();
        ImConfig {
            id: Some(id),
            name,
            current_user_id,
            content,
            status: status2,
            create_time: parse_to_time(create_time_str),
            update_time: parse_to_time(update_time_str),
        }
    }
}